package com.easylinkin.linkappapi.safe.service.impl;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.word.WordExportUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.common.service.OSSService;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.common.utils.excel.ExcelConstant;
import com.easylinkin.linkappapi.common.utils.excel.ExcelTools;
import com.easylinkin.linkappapi.common.utils.file.FileExt;
import com.easylinkin.linkappapi.common.utils.file.ZipFileUtil;
import com.easylinkin.linkappapi.common.utils.io.OutputStreamUtil;
import com.easylinkin.linkappapi.danger.entity.Danger;
import com.easylinkin.linkappapi.danger.service.DangerService;
import com.easylinkin.linkappapi.danger.service.DangerTypeService;
import com.easylinkin.linkappapi.facerecognition.service.oss.ObjectStorageInternalService;
import com.easylinkin.linkappapi.openapi.vo.SafetyCheckHiddenDangerPageVo;
import com.easylinkin.linkappapi.photoalbum.util.ExportUtil;
import com.easylinkin.linkappapi.safe.dao.DangerousDangerRefMapper;
import com.easylinkin.linkappapi.safe.dao.HiddenDangerInfoMapper;
import com.easylinkin.linkappapi.safe.dao.HiddenDangerMapper;
import com.easylinkin.linkappapi.safe.dto.HiddenDangerCountDTO;
import com.easylinkin.linkappapi.safe.dto.HiddenDangerDTO;
import com.easylinkin.linkappapi.safe.dto.HiddenDangerPhotoAlbumDTO;
import com.easylinkin.linkappapi.safe.dto.HiddenDangerPhotoAlbumQueryDTO;
import com.easylinkin.linkappapi.safe.entity.DangerousDangerRef;
import com.easylinkin.linkappapi.safe.entity.HiddenDanger;
import com.easylinkin.linkappapi.safe.entity.HiddenDangerInfo;
import com.easylinkin.linkappapi.safe.entity.vo.HiddenDangerVo;
import com.easylinkin.linkappapi.safe.service.HiddenDangerService;
import com.easylinkin.linkappapi.safe.service.InspectionTaskService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.mapper.LinkappTenantMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * HiddenDanger表服务实现类
 *
 * @author CodeGenerator
 * @date 2022/07/21
 */
@Slf4j
@Service("hiddenDangerService")
public class HiddenDangerServiceImpl extends ServiceImpl<HiddenDangerMapper, HiddenDanger>
		implements HiddenDangerService {
	@Resource
	private CommonService commonService;
	@Resource
	private LinkappUserContextProducer linkappUserContextProducer;

	@Autowired
	private HiddenDangerInfoMapper hiddenDangerInfoMapper;

	@Autowired
	private HiddenDangerInfoServiceImpl hiddenDangerInfoService;

	@Autowired
	private DangerService dangerService;

	@Autowired
	private DangerTypeService dangerTypeService;

	@Autowired
	private DangerousDangerRefMapper dangerousDangerRefMapper;

	@Autowired
	private InspectionTaskService inspectionTaskService;

	@Autowired
	private LinkappTenantMapper linkappTenantMapper;

	@Override
	public HiddenDangerDTO saveOne(HiddenDanger hiddenDanger) {
		//type = 2为添加排查
		commonService.setCreateAndModifyInfo(hiddenDanger);

		// 校验参数
		validParamRequired(hiddenDanger);

		if (!Integer.valueOf(2).equals(hiddenDanger.getType())){
			validParamFormat(hiddenDanger);
		}

		// 设置基础属性
		this.setBase(hiddenDanger);

		boolean onSave = save(hiddenDanger);
		if (onSave && !Integer.valueOf(2).equals(hiddenDanger.getType())) {
			//20221121变更，兼容企业级
			boolean isEnterprise = false;
			Integer sourceType = hiddenDanger.getEnterpriseSourceType();
			if(sourceType != null && sourceType.intValue() == 2){
				isEnterprise = true;
			}
			if (hiddenDanger.getIsSceneRectify() == 1) {

				// 发送消息提醒整改人整改
				if(isEnterprise){
					//企业级
					hiddenDangerInfoService.saveMessage("现场整改通过", "您有一条相关的隐患记录已现场通过!",
							String.valueOf(hiddenDanger.getRectifyUid()), hiddenDanger,true);
				}else{
					hiddenDangerInfoService.saveMessage("现场整改通过", "您有一条相关的隐患记录已现场通过!",
							String.valueOf(hiddenDanger.getRectifyUid()), hiddenDanger.getId(),true);
				}

			} else {
				if(isEnterprise){
					// 发送消息提醒整改人整改
					hiddenDangerInfoService.saveMessage("隐患整改提醒", "您有一条待整改的隐患，请及时处理!",
							String.valueOf(hiddenDanger.getRectifyUid()), hiddenDanger,true);
				}else{
					// 发送消息提醒整改人整改
					hiddenDangerInfoService.saveMessage("隐患整改提醒", "您有一条待整改的隐患，请及时处理!",
							String.valueOf(hiddenDanger.getRectifyUid()), hiddenDanger.getId(),true);
				}

			}
			// 发送消息通知人
			if(StringUtils.isNotEmpty(hiddenDanger.getNoticerIds())){
				Danger oneById = dangerService.getOneById(hiddenDanger.getHiddenDangerId());
				StringBuilder sb = new StringBuilder();
				sb.append(oneById.getContent());
				if(StringUtils.isNotEmpty(hiddenDanger.getSupplementRemarks())){
					sb.append(" ");
					sb.append(hiddenDanger.getSupplementRemarks());
				}
				String title = "安全隐患检查通知";
				List<String> userIds = Arrays.asList(hiddenDanger.getNoticerIds().split(","));
				boolean finalIsEnterprise = isEnterprise;
				userIds.forEach(p -> {
					// 消息中心
					if(finalIsEnterprise){
						hiddenDangerInfoService.saveMessage(title, sb.toString(),
								p, hiddenDanger, true);
					}else{
						hiddenDangerInfoService.saveMessage(title, sb.toString(),
								p, hiddenDanger.getId(), true);
					}
				});
			}
		}
		//保存后更新任务项状态
		if (null != hiddenDanger.getTaskId()){
			inspectionTaskService.computeStatus(hiddenDanger.getTaskId());
		}
		//这里不面向对象传参搞死人啊，到这里还在套娃，这方法写的真差
		//return getOneById(hiddenDanger.getId());
		return getOneByDanger(hiddenDanger);
	}

	private HiddenDangerDTO getOneByDanger(HiddenDanger hiddenDanger) {
		String id = hiddenDanger.getId();
		HiddenDangerDTO hiddenDangerDTO = new HiddenDangerDTO();

		hiddenDangerDTO.setId(hiddenDanger.getId());
		hiddenDangerDTO.setTenantId(hiddenDanger.getTenantId());
		hiddenDangerDTO.setRectifyUid(hiddenDanger.getRectifyUid());
		hiddenDangerDTO.setCheckUid(hiddenDanger.getCheckUid());
		hiddenDangerDTO.setEnterpriseSourceType(hiddenDanger.getEnterpriseSourceType());

		//根据id查询
		hiddenDangerDTO.setIdFlag(true);

		IPage<HiddenDangerDTO> iPage = this.selectListByPage(new Page<>(0, 1), hiddenDangerDTO);

		if (iPage.getRecords().size() > 0) {

			hiddenDangerDTO = iPage.getRecords().get(0);
		}

		List<HiddenDangerInfo> infos = hiddenDangerInfoMapper.selectByHiddenDangerId(String.valueOf(id));

		hiddenDangerDTO.setInfos(infos);

		return hiddenDangerDTO;
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateOne(HiddenDanger hiddenDanger) {
		Assert.notNull(hiddenDanger.getId(), "id不能为空");
		commonService.setModifyInfo(hiddenDanger);
		// hiddenDanger.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
		validRepeat(hiddenDanger);
		validParamFormat(hiddenDanger);
		return updateById(hiddenDanger);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateOneNew(HiddenDanger hiddenDanger) {
		Assert.notNull(hiddenDanger.getId(), "id不能为空");
		validParamFormatNew(hiddenDanger);
		return updateById(hiddenDanger);
	}

	/**
	 * 校验参数格式
	 */
	private void validParamFormatNew(HiddenDanger hiddenDanger) {
		String requirements = hiddenDanger.getRectifyRequirements() == null ? "" : hiddenDanger.getRectifyRequirements();
		String remark = hiddenDanger.getSupplementRemarks() == null ? "" : hiddenDanger.getSupplementRemarks();
		Assert.isTrue(requirements.length() <= 140, "整改要求字数过长");
		Assert.isTrue(remark.length() <= 140, "补充说明字数过长");
	}

	@Override
	public boolean modifyRectifyUser(HiddenDanger hiddenDanger) {
		Assert.notNull(hiddenDanger.getId(), "id不能为空");
		Assert.notNull(hiddenDanger.getRectifyUid(), "整改人id不能为空");
		HiddenDanger old = baseMapper.getOneById(hiddenDanger.getId());
		Assert.isTrue(null != old, "隐患不存在");
		Assert.isTrue(old.getStatus() == 0, "隐患状态不为待整改");
		if (updateById(hiddenDanger)) {
			// 发送消息提醒整改人整改
			Integer enterpriseSourceType = old.getEnterpriseSourceType();
			if(enterpriseSourceType != null && enterpriseSourceType.intValue() == 2) {
				hiddenDangerInfoService.saveMessage("隐患整改提醒", "您有一条待整改的隐患，请及时处理!",
						String.valueOf(hiddenDanger.getRectifyUid()), old, true);
			}else{
				hiddenDangerInfoService.saveMessage("隐患整改提醒", "您有一条待整改的隐患，请及时处理!",
						String.valueOf(hiddenDanger.getRectifyUid()), hiddenDanger.getId(), true);
			}
			return true;
		}
		return false;
	}

	@Override
	public boolean modifyCheckUser(HiddenDanger hiddenDanger) {
		Assert.notNull(hiddenDanger.getId(), "id不能为空");
    Assert.notNull(hiddenDanger.getCheckUid(), "复查人id不能为空");
		HiddenDanger old = baseMapper.getOneById(hiddenDanger.getId());
		Assert.isTrue(null != old, "隐患不存在");
    Assert.isTrue(old.getStatus() == 1 || old.getStatus() == 0, "隐患状态不为待复查");
		if (updateById(hiddenDanger)) {
			if (old.getStatus() == 1) {
				// 给复查人发送复查消息
				Integer enterpriseSourceType = old.getEnterpriseSourceType();
				if(enterpriseSourceType != null && enterpriseSourceType.intValue() == 2){
					hiddenDangerInfoService.saveMessage("隐患复查提醒", "您有一条待复查隐患记录，请尽快处理!",
							String.valueOf(hiddenDanger.getCheckUid()), old, true);
				}else{
					hiddenDangerInfoService.saveMessage("隐患复查提醒", "您有一条待复查隐患记录，请尽快处理!",
							String.valueOf(hiddenDanger.getCheckUid()), hiddenDanger.getId(), true);
				}

			}
			return true;
		}
		return false;
	}

    @Override
    public RestMessage safetyCheckHiddenCount(SafetyCheckHiddenDangerPageVo safetyCheckHiddenDangerPageVo) {
		String ids = safetyCheckHiddenDangerPageVo.getIds();

		List<HiddenDangerCountDTO> countList = baseMapper.countGroupByCheckAndStatus(safetyCheckHiddenDangerPageVo);
		//状态：0：待整改，1：待复查，2：合格，3：无需整改
		//转换:0,1都是未完成，2、3是已完成
		Map<Long,Map<String,Integer>> checkCountMp = new HashMap<>();
		if(CollectionUtil.isNotEmpty(countList)){
			countList.stream().forEach(c->{
				Long checkId = c.getEnterpriseSafetyCheckId();
				Integer status = c.getStatus();
				Integer totalNum = c.getTotalNum();
				if (checkId != null){
					Map<String,Integer> countMap = checkCountMp.get(checkId);
					if (CollectionUtil.isEmpty(countMap)) {
						countMap = new HashMap<>();
					}
					Integer undoneNum = countMap.get("undoneNum");
					if (undoneNum == null){
						undoneNum = 0;
					}

					Integer endNum = countMap.get("endNum");
					if (endNum == null){
						endNum = 0;
					}
					if(status != null){
						if(status.intValue() == 0 || status.intValue() == 1){
							undoneNum += totalNum;
						}

						if(status.intValue() == 2 || status.intValue() == 3){
							endNum += totalNum;
						}

					}
					countMap.put("undoneNum",undoneNum);
					countMap.put("endNum",endNum);
					checkCountMp.put(checkId,countMap);
				}
			});
		}
        return RestBuilders.successBuilder().data(checkCountMp).build();
    }

	@Override
	public HiddenDangerCountDTO getCountEnterprise(RequestModel<HiddenDangerDTO> requestModel) {
		//这里的统计代码复制getCount修改数据查询逻辑，计算逻辑与原先一致，避免计算精度，但是说实话，这个计算是自己写的太粗糙
		//HiddenDangerCountDTO countDTO = baseMapper.getStatistics(linkappUserContextProducer.getCurrent().getTenantId(),endTime,content,linkUnitId,rectifyUid,startTime);
		HiddenDangerDTO hiddenDangerDTO = requestModel.getCustomQueryParams();

		HiddenDangerCountDTO countDTO = baseMapper.getCountEnterprise(hiddenDangerDTO);
		//以下根业务端计算一致
		if (countDTO.getTotalNum() == 0) {

			countDTO.setFinishRate("0");
			countDTO.setInTimeFinishedRate("0");

		} else {

			float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();
			// 格式化小数
			DecimalFormat df = new DecimalFormat("0.00");
			// 完成率 已闭合/总数
			countDTO.setFinishRate(df.format(num * 100) + "%");
			// 及时整改率：按时整改数/总数
			float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum();

			countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
		}

		return countDTO;
	}

	@Override
	public IPage<HiddenDangerCountDTO> getTenantIdCount(RequestModel<HiddenDangerDTO> requestModel) {
		HiddenDangerDTO hiddenDangerDTO = requestModel.getCustomQueryParams();
		Page page = requestModel.getPage();
		IPage<HiddenDangerCountDTO> countDataPage = baseMapper.getTenantIdCountList(page,hiddenDangerDTO);
		if(CollectionUtil.isNotEmpty(countDataPage.getRecords())){
			List<HiddenDangerCountDTO> countDTOLs = countDataPage.getRecords();
			countDTOLs.stream().forEach(countDTO -> {
				//以下根业务端计算一致
				if (countDTO.getTotalNum() == 0) {
					countDTO.setFinishRate("0");
					countDTO.setInTimeFinishedRate("0");
				} else {
					float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();
					// 格式化小数
					DecimalFormat df = new DecimalFormat("0.00");
					// 完成率 已闭合/总数
					countDTO.setFinishRate(df.format(num * 100) + "%");
					// 及时整改率：按时整改数/总数
					float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum();
					countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
				}
			});
		}

		return countDataPage;
	}

	@Override
	public HiddenDangerDTO getOneByIdAndSourceType(Serializable id, Integer sourceType) {
		HiddenDangerDTO hiddenDangerDTO = new HiddenDangerDTO();

		hiddenDangerDTO.setId(String.valueOf(id));
		//根据id查询
		hiddenDangerDTO.setIdFlag(true);
		hiddenDangerDTO.setEnterpriseSourceType(sourceType);

		//先直接预先查询(20221122为了兼容企业端增加，说实话这个方法写的真xx)
		HiddenDanger hiddenDanger = baseMapper.selectById(id);
		if(hiddenDanger != null) {
			Integer enterpriseSourceType = hiddenDanger.getEnterpriseSourceType();
			if(enterpriseSourceType != null && enterpriseSourceType.intValue() == 2){
				hiddenDangerDTO.setEnterpriseSourceType(enterpriseSourceType);
			}
		}

		IPage<HiddenDangerDTO> iPage = this.selectListByPage(new Page<>(0, 1), hiddenDangerDTO);

		if (iPage.getRecords().size() > 0) {

			hiddenDangerDTO = iPage.getRecords().get(0);
		}

		List<HiddenDangerInfo> infos = hiddenDangerInfoMapper.selectByHiddenDangerId(String.valueOf(id));

		hiddenDangerDTO.setInfos(infos);

		return hiddenDangerDTO;
	}

	@Override
	public IPage<HiddenDanger> selectPage(Page page, HiddenDanger hiddenDanger) {

		return baseMapper.selectPage(page, hiddenDanger);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteByIds(List<String> idList) {
		//移除关联关系
		UpdateWrapper<DangerousDangerRef> updateWrapper=new UpdateWrapper<>();
		updateWrapper.in("danger_id",idList);
		updateWrapper.set("delete_state",0);
		dangerousDangerRefMapper.update(null,updateWrapper);

		//更新任务项状态
		idList.forEach(id ->{
			HiddenDanger hiddenDanger = baseMapper.selectById(id);
			if (null != hiddenDanger &&  null != hiddenDanger.getTaskId()){
				inspectionTaskService.computeStatus(hiddenDanger.getTaskId());
			}
		});
		return removeByIds(idList);
	}

	@Override
	public void export(HiddenDanger hiddenDanger, HttpServletRequest request, HttpServletResponse response) {

		IPage<HiddenDanger> page = selectPage(new Page(0, -1), hiddenDanger);
		List<HiddenDanger> records = page.getRecords();
		List<HiddenDangerVo> hiddenDangerVos = new ArrayList<>();
		for (HiddenDanger expert : records) {
			// hiddenDangerVos.add(new HiddenDangerVo(expert));
		}

		String keyValue = "名称:name,租户id:tenantId";
		String title = "HiddenDanger导出数据";
		String fileName = title + ".xls";
		try {
			OutputStream outputStream = OutputStreamUtil.getOutputStream(request, response, fileName);
			ExcelTools.exportExcel(outputStream, keyValue, hiddenDangerVos, ExcelConstant.XLS, title);
			response.flushBuffer();
			outputStream.close();
		} catch (IOException e) {
			log.error("excel导出失败", e);
			throw new RuntimeException("excel导出失败！IOException异常" + e.getMessage());
		} catch (Exception e) {
			log.error("excel导出失败", e);
			throw new RuntimeException("excel导出失败！" + e.getMessage());
		}
	}

	@Override
	public HiddenDangerDTO getOneById(Serializable id) {
		HiddenDangerDTO hiddenDangerDTO = new HiddenDangerDTO();

		hiddenDangerDTO.setId(String.valueOf(id));
		//根据id查询
		hiddenDangerDTO.setIdFlag(true);

		//先直接预先查询(20221122为了兼容企业端增加，说实话这个方法写的真xx)
		HiddenDanger hiddenDanger = baseMapper.selectById(id);
		if(hiddenDanger != null) {
			Integer enterpriseSourceType = hiddenDanger.getEnterpriseSourceType();
			if(enterpriseSourceType != null && enterpriseSourceType.intValue() == 2){
				hiddenDangerDTO.setEnterpriseSourceType(enterpriseSourceType);
			}
		}

		IPage<HiddenDangerDTO> iPage = this.selectListByPage(new Page<>(0, 1), hiddenDangerDTO);

		if (iPage.getRecords().size() > 0) {

			hiddenDangerDTO = iPage.getRecords().get(0);
		}

		List<HiddenDangerInfo> infos = hiddenDangerInfoMapper.selectByHiddenDangerId(String.valueOf(id));

		hiddenDangerDTO.setInfos(infos);

		return hiddenDangerDTO;
	}

	/**
	 * 校验重复
	 */
	private void validRepeat(HiddenDanger hiddenDanger) {
		QueryWrapper<HiddenDanger> queryWrapper = new QueryWrapper<>();
		// queryWrapper.eq("name", hiddenDanger.getName());
		// queryWrapper.eq("tenant_id",
		// linkappUserContextProducer.getNotNullCurrent().getTenantId());
		List<HiddenDanger> list = baseMapper.selectList(queryWrapper);
		if (list.size() == 0) {
			return;
		}
		if (list.size() > 1) {
			throw new BusinessException("名称有重复");
		}
		if (ObjectUtils.isEmpty(hiddenDanger.getId())) {
			throw new BusinessException("名称已存在");
		}
		if (!hiddenDanger.getId().equals(list.get(0).getId())) {
			throw new BusinessException("名称已存在");
		}

	}

	/**
	 * 校验参数必填
	 */
	private void validParamRequired(HiddenDanger hiddenDanger) {
		Assert.notNull(hiddenDanger, "参数为空");
		//type = 2为排查
		if (!Integer.valueOf(2).equals(hiddenDanger.getType())){
			Assert.notNull(hiddenDanger.getCheckUid(), "复查人为空");
			Assert.notNull(hiddenDanger.getRectifyUid(), "整改人为空");
			Assert.isTrue(StringUtils.isNotBlank(hiddenDanger.getHiddenDangerId()), "安全隐患为空");
			Assert.isTrue(StringUtils.isNotBlank(hiddenDanger.getLinkUnitId()), "参建单位为空");
			Assert.notNull(hiddenDanger.getRectifyEndTime(), "整改时限");
			Assert.isTrue(StringUtils.isNotBlank(hiddenDanger.getRectifyRequirements()), "整改要求");
			Assert.notNull(hiddenDanger.getIsSceneRectify(), "是否现场整改");
//			Assert.notNull(hiddenDanger.getCheckPartId(), "检查部位为空");
		}else {
			Assert.isTrue(StringUtils.isNotBlank(hiddenDanger.getRectifyRequirements()), "检查项");
//			Assert.notNull(hiddenDanger.getCheckPartId(), "检查部位为空");
		}
		if(StringUtils.isNotEmpty(hiddenDanger.getNoticerIds())){
			List<String> userIds = Arrays.asList(hiddenDanger.getNoticerIds().split(","));
			Assert.isTrue(userIds.size()<=10, "通知人最多只能选10人");
		}
	}

	/**
	 * 校验参数格式
	 */
	private void validParamFormat(HiddenDanger hiddenDanger) {

		System.out.println(hiddenDanger.getRectifyRequirements().length());
		Assert.isTrue(hiddenDanger.getRectifyRequirements().length() <= 140, "整改要求字数过长");
		Assert.isTrue(hiddenDanger.getSupplementRemarks().length() <= 140, "补充说明字数过长");
	}

	private void setBase(HiddenDanger hiddenDanger) {

		hiddenDanger.setCreateTime(new Date());

		LinkappUser linkappUser = null;
		String tenantId = null;
		Long createUid = null;
		Integer sourceType = hiddenDanger.getEnterpriseSourceType();
		if(sourceType != null && sourceType.intValue() == 2){
			tenantId = hiddenDanger.getTenantId();
		}else{
			linkappUser = linkappUserContextProducer.getCurrent();
			createUid = linkappUser.getId();
			tenantId = linkappUser.getTenantId();
		}
		hiddenDanger.setCreateUid(createUid); // 设置创建人

		hiddenDanger.setTenantId(tenantId); // 设置租户id

		// 直接现场整改，默认状态为合格
		if (!Integer.valueOf(2).equals(hiddenDanger.getType())){
			if (hiddenDanger.getIsSceneRectify() == 1) {

				hiddenDanger.setStatus(2);// 合格
				hiddenDanger.setCloseTime(new Date()); // 现场完成设置关闭时间为当前时间
			} else {
				hiddenDanger.setStatus(0);// 默认状态为待整改
			}
			// hiddenDanger.setIsOverdue(0); //默认状态为未超期(弃用)

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(hiddenDanger.getRectifyEndTime());
			calendar.set(Calendar.HOUR_OF_DAY, 23);
			calendar.set(Calendar.MINUTE, 59);
			calendar.set(Calendar.SECOND, 59);

			// 整改时限默认为所选最后一分钟结束
			hiddenDanger.setRectifyEndTime(calendar.getTime());

			// 整改时限小于当前时间直接设置为已超期
//			if (hiddenDanger.getRectifyEndTime().before(new Date())) {
//
//				hiddenDanger.setIsOverdue(1);// 已超期
//			}
		}else {
			//无需整改
			hiddenDanger.setStatus(3);
		}
	}

	@Override
	public IPage<HiddenDangerDTO> selectListByPage(Page page, HiddenDangerDTO hiddenDangerDTO) {
		Integer sourceType = hiddenDangerDTO.getEnterpriseSourceType();
		Long rectifyUid = hiddenDangerDTO.getRectifyUid();
		Long checkUid = hiddenDangerDTO.getCheckUid();
		if(sourceType == null || sourceType.intValue() == 1) {
			//项目级
			LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();
			rectifyUid = linkappUser.getId();
			checkUid = linkappUser.getId();
			hiddenDangerDTO.setTenantId(linkappUser.getTenantId());
		}

		if (hiddenDangerDTO.getIsFilter() == null) {
			hiddenDangerDTO.setIsFilter(0);
		}

		// 根据状态隔离数据
		if (hiddenDangerDTO.getStatus() != null && hiddenDangerDTO.getIsFilter() == 1) {
			if (hiddenDangerDTO.getStatus() == 0) {
				// 待整改
				hiddenDangerDTO.setRectifyUid(rectifyUid);

			} else if (hiddenDangerDTO.getStatus() == 1) {
				// 待整改
				hiddenDangerDTO.setCheckUid(checkUid);
			}
		}
		//todo 暂时只查询隐患，后续可能修改 但是id查询得查全部
		//type = 1为隐患
		if (null == hiddenDangerDTO.getIdFlag()){
			hiddenDangerDTO.setType(1);
		}
		IPage<HiddenDangerDTO> hiddenDangerDTOIPage = baseMapper.selectListByPage(page, hiddenDangerDTO);
		hiddenDangerDTOIPage.getRecords().forEach(record->{
			String id = record.getId();
			List<HiddenDangerInfo> hiddenDangerInfos = hiddenDangerInfoMapper.selectByHiddenDangerId(id);
			record.setInfos(hiddenDangerInfos);
			//我不太喜欢这种对结果在遍历查询的方式，但是现在是改别人的扩展，既然已经有遍历了就加这里吧
			if(sourceType != null && sourceType.intValue() == 2) {
				//企业级
				String recordTenantId = record.getTenantId();
				LinkappTenant linkappTenant = linkappTenantMapper.getById(recordTenantId);
				record.setLinkappTenant(linkappTenant);
			}
		});
		return hiddenDangerDTOIPage;
	}



	@Override
	public HiddenDangerCountDTO getCount(String content, String linkUnitId, Long rectifyUid,
			Date startTime, Date endTime,String tenantId) {
		String ten = tenantId != null ? tenantId : (linkappUserContextProducer.getCurrent() != null ? linkappUserContextProducer.getCurrent().getTenantId() : null);
		HiddenDangerCountDTO countDTO = baseMapper.getStatistics(ten,endTime,content,linkUnitId,rectifyUid,startTime);

		if (countDTO.getTotalNum() == 0) {

			countDTO.setFinishRate("0");
			countDTO.setInTimeFinishedRate("0");

		} else {

			float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();

			DecimalFormat df = new DecimalFormat("0.00");// 格式化小数

			countDTO.setFinishRate(df.format(num * 100) + "%");// 完成率 已闭合/总数

			float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum(); // 及时整改率：按时整改数/总数

			countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
		}

		return countDTO;
	}

	@Override
	public List<HiddenDangerCountDTO> getUnitIdCount(Date startTime, Date endTime, String tenantId2) {
		LinkappUser curr = linkappUserContextProducer.getCurrent();
		String tenantId = curr != null ? curr.getTenantId() : null;
		tenantId = tenantId2 != null ? tenantId2 : tenantId;
		List<HiddenDangerCountDTO> countDTOList = baseMapper.getUnitIdStatistics(tenantId, startTime, endTime);
		countDTOList.forEach(countDTO->{
			if (countDTO.getTotalNum() == 0) {
				countDTO.setFinishRate("0");
				countDTO.setInTimeFinishedRate("0");
			} else {
				float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();
				DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
				countDTO.setFinishRate(df.format(num * 100) + "%");// 完成率 已闭合/总数
				float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum(); // 及时整改率：按时整改数/总数
				countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
			}
		});
		return countDTOList;
	}

	@Override
	public IPage<HiddenDangerPhotoAlbumDTO> selectPhotoAlbumByPage(Page page,
			HiddenDangerPhotoAlbumQueryDTO queryDTO) {
		queryDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
		IPage<HiddenDangerPhotoAlbumDTO> pagelist = baseMapper
				.selectPhotoAlbumByPage(page, queryDTO);
		pagelist.getRecords().forEach(p->setPhotos(p));
		return pagelist;
	}

	@Override
	public int photoAlbumCount(HiddenDangerPhotoAlbumQueryDTO queryDTO) {
		//项目id 过滤
		queryDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
		List<HiddenDangerPhotoAlbumDTO> list = baseMapper
				.selectPhotoAlbumByPage(queryDTO);
		int total = 0;
		if(CollectionUtil.isNotEmpty(list)){
			for (HiddenDangerPhotoAlbumDTO dto : list) {
				setPhotos(dto);
				if(CollectionUtil.isNotEmpty(dto.getPhotos())){
					total += dto.getPhotos().size();
				}
			}
		}
		return total;
	}

	private void setPhotos(HiddenDangerPhotoAlbumDTO dto){
		List<String> photos = new ArrayList<>();
		String scenePhoto = dto.getScenePhoto();
		String checkPhotos = dto.getCheckPhotos();
		String rectifyPhotos = dto.getRectifyPhotos();
		if(StringUtils.isNotEmpty(scenePhoto)){
			photos.addAll(Arrays.asList(scenePhoto.split(",")));
		}
		if(StringUtils.isNotEmpty(checkPhotos)){
			photos.addAll(Arrays.asList(checkPhotos.split(",")));
		}
		if(StringUtils.isNotEmpty(rectifyPhotos)){
			photos.addAll(Arrays.asList(rectifyPhotos.split(",")));
		}
		dto.setPhotos(photos);
	}

	@Autowired
	@Qualifier("ossInternal")
	private ObjectStorageInternalService ossClient;

	@Autowired
	private OSSService ossService;

	@Value("${oss.dir}")
	private String dir;

	@Value("${oss.bucket}")
	private String bucket;

	@Value("${oss.readHost}")
	private String readHost;

	private final String prefix = "安全隐患";

	@Override
	public String exportPhotoAlbum(HiddenDangerPhotoAlbumQueryDTO dto) {
		//项目id 过滤
		dto.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
		String fileName = null;
		List<HiddenDangerPhotoAlbumDTO> list = baseMapper
				.selectPhotoAlbumByPage(dto);
		List<FileExt> fileExtList = new ArrayList<>();
		if(CollectionUtil.isNotEmpty(list)){

			int total = 0;
			if(CollectionUtil.isNotEmpty(list)){
				for (HiddenDangerPhotoAlbumDTO p : list) {
					setPhotos(p);
					if(CollectionUtil.isNotEmpty(p.getPhotos())){
						total += p.getPhotos().size();
					}
				}
			}
			if(total > 100){
				throw new RuntimeException("相册导出失败！相册导出不能超过100张");
			}

			for (HiddenDangerPhotoAlbumDTO p : list) {
				List<String> photos = p.getPhotos();
				if (CollectionUtil.isNotEmpty(photos)) {
					List<String> fileUrlList = new ArrayList<>();
					for (int i = 0; i < photos.size(); i++) {
						String singleFile = photos.get(i);
						fileUrlList.add(singleFile);
					}
					long count = 0;
					for (String url : fileUrlList) {

						if (StringUtils.isNotEmpty(url)) {
							url = url.replace("+", "%2B");
							url = url.replace("&", "%26");
						} else {
							log.error("打包失败：名称为空");
							continue;
						}
						FileExt fileInfoByUrl = ExportUtil
								.getFileInfoByUrl(url,prefix,DateUtil.getyyyyMMddHHmmssSSSNumberString(p.getCreateTime()),p.getFullName(),count);
						if (null != fileInfoByUrl && null != fileInfoByUrl.getInputStream()) {
							fileExtList.add(fileInfoByUrl);
							count ++;
						} else {
							log.error("打包失败：名称【{}】", url);
						}
					}
				}
			}

		}


		//开始导出
		InputStream fileInputStream = null;
		try {
			String today = DateUtil.getyyyyMMddHHmmssSSSNumberString(new Date());
			fileInputStream = ZipFileUtil.getFileInputStream(today, fileExtList);
			//上传文件到oss
			String resultFilename =
					"安全隐患"+"_"+ today + ".zip";
			ossClient.putObject(bucket, resultFilename, fileInputStream, "application/octet-stream");
			fileName = ossService.generateUrl(resultFilename);
		} catch (Exception e) {
			log.error("打包失败：", e);
		} finally {
			// 关闭流
			try {
				if (null != fileInputStream) {
					fileInputStream.close();
				}
			} catch (IOException e) {
				log.error("打包失败：", e);
			}
		}
		return fileName;
	}


	@Override
	public List<HiddenDangerCountDTO> getPartCount(Date startTime, Date endTime, String tenantId2) {
		String tenantId = tenantId2;
		if (StringUtils.isEmpty(tenantId)) {
			LinkappUser user = linkappUserContextProducer.getCurrent();
			tenantId = user != null ? user.getTenantId() : null;
		}
		List<HiddenDangerCountDTO> countDTOList = baseMapper.getPartCount(tenantId,startTime,endTime);
		countDTOList.forEach(countDTO->{
			if (countDTO.getTotalNum() == 0) {
				countDTO.setFinishRate("0");
				countDTO.setInTimeFinishedRate("0");
			} else {
				float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();
				DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
				countDTO.setFinishRate(df.format(num * 100) + "%");// 完成率 已闭合/总数
				float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum(); // 及时整改率：按时整改数/总数
				countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
			}
		});
		return countDTOList;
	}

	@Override
	public List<HiddenDangerCountDTO> getTypeCount(Date startTime, Date endTime, String tenantId2) {
		LinkappUser curr = linkappUserContextProducer.getCurrent();
		String tenantId = null;
		if (curr != null) {
			tenantId = curr.getTenantId();
		}
		tenantId = !StringUtils.isEmpty(tenantId2) ? tenantId2 : tenantId;
		List<HiddenDangerCountDTO> countDTOList = baseMapper.getTypeCount(tenantId, startTime, endTime);
		countDTOList.forEach(countDTO->{
			if (countDTO.getTotalNum() == 0) {
				countDTO.setFinishRate("0");
				countDTO.setInTimeFinishedRate("0");
			} else {
				float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();
				DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
				countDTO.setFinishRate(df.format(num * 100) + "%");// 完成率 已闭合/总数
				float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum(); // 及时整改率：按时整改数/总数
				countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
			}
		});
		//进行按照数量大小排序
		countDTOList.sort(new Comparator<HiddenDangerCountDTO>() {
			@Override
			public int compare(HiddenDangerCountDTO o1, HiddenDangerCountDTO o2) {
				return o2.getTotalNum()-o1.getTotalNum();
			}
		});
		return countDTOList;
	}

	@Override
	public List<HiddenDangerCountDTO> getPersonCount() {
		List<HiddenDangerCountDTO> countDTOList = baseMapper.getPersonCount(linkappUserContextProducer.getCurrent().getTenantId());
		countDTOList.forEach(countDTO->{
			if (countDTO.getTotalNum() == 0) {
				countDTO.setFinishRate("0");
				countDTO.setInTimeFinishedRate("0");
			} else {
				float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();
				DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
				countDTO.setFinishRate(df.format(num * 100) + "%");// 完成率 已闭合/总数
				float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum(); // 及时整改率：按时整改数/总数
				countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
			}
		});
		return countDTOList;
	}

	@Override
	public List<HiddenDangerCountDTO> getMonthCount() {
		//获取前12个月
		Date endTime = new Date();
		Date startMonthTime = DateUtil.addMonth(endTime, -11);
		Date nowMonthFirstDay = DateUtil.getNowMonthFirstDay(startMonthTime);
		Date startTime = DateUtil.getTodayStartTime(nowMonthFirstDay);
		List<HiddenDangerCountDTO> countDTOList = baseMapper.getMonthCount(linkappUserContextProducer.getCurrent().getTenantId(),startTime,endTime);
		countDTOList.forEach(countDTO->{
			if (countDTO.getTotalNum() == 0) {
				countDTO.setFinishRate("0");
				countDTO.setInTimeFinishedRate("0");
			} else {
				float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();
				DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
				countDTO.setFinishRate(df.format(num * 100) + "%");// 完成率 已闭合/总数
				float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum(); // 及时整改率：按时整改数/总数
				countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
			}
		});
		return countDTOList;
	}

	@Override
	public List<HiddenDangerCountDTO> getDayCount() {
		Date endTime = new Date();
		Date startDayTime = DateUtil.addDay(endTime, -15);
		Date startTime = DateUtil.getTodayStartTime(startDayTime);
		endTime = DateUtil.getTodayStartTime(endTime);
		String tenantId = linkappUserContextProducer.getCurrent().getTenantId();
		List<HiddenDangerCountDTO> countDTOList = baseMapper.getDayCount(tenantId,startTime,endTime);
//		countDTOList.forEach(countDTO->{
//			if (countDTO.getTotalNum() == 0) {
//				countDTO.setFinishRate("0");
//				countDTO.setInTimeFinishedRate("0");
//			} else {
//				float num = (float) countDTO.getQualifiedNum() / countDTO.getTotalNum();
//				DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
//				countDTO.setFinishRate(df.format(num * 100) + "%");// 完成率 已闭合/总数
//				float inTime = (float) countDTO.getInTimeFinishedNum() / countDTO.getTotalNum(); // 及时整改率：按时整改数/总数
//				countDTO.setInTimeFinishedRate(df.format(inTime * 100) + "%");
//			}
//		});
		//如果缺失则进行填充
		filterNullData(tenantId,countDTOList,startTime);
		return countDTOList;
	}

	/**
	 * @Description: 导出检查记录表/整改通知书
	 * @author kan yuanfeng
	 * @date 2020/11/04 11:42
	 */
	@Override
	public XWPFDocument getWord(Integer type, Integer wordType, List<String> ids, String tenantId) throws Exception {
		//组织数据
		String[] wordTypes = {"","日检","周检","月检","节假日","日常检查","专项检查"};
		Map<String, Object> map = new HashMap<>();
		map.put("wordType",wordTypes[wordType]);
		//项目信息
		if(StringUtils.isBlank(tenantId)){
			tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
		}
		LinkappTenant query = new LinkappTenant();
		query.setId(tenantId);
		LinkappTenant linkappTenant = linkappTenantMapper.selectLinkappTenant(query);
		map.put("projectName",linkappTenant.getPlatformProjectName());
		//查询数据
		List<HiddenDangerDTO> list = new ArrayList<>();
		List<HiddenDangerDTO> finalList = list;
		ids.forEach(id -> finalList.add(this.getOneById(id)));
		//检查时间
		list = finalList.stream().sorted(Comparator.comparing(HiddenDangerDTO::getCreateTime).reversed())
				.collect(Collectors.toList());
		//复查
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
		map.put("checkTime",sdf.format(list.get(0).getCreateTime()));
		//检查部位
		List<String> partFullNames = list.stream()
				.filter(l -> StringUtils.isNotBlank(l.getCheckPartFullName()))
				.map(l -> l.getCheckPartFullName()).collect(Collectors.toList());
		if (partFullNames.size() > 0){
			map.put("position",StringUtils.join(partFullNames,"，"));
		}
		//检查内容
		if (type==1){
			List<String> contents = list.stream().filter(l -> StringUtils.isNotBlank(l.getContent()))
					.map(l -> l.getContent()+(StringUtils.isNotBlank(l.getSupplementRemarks())?("；"+l.getSupplementRemarks()):"")).collect(Collectors.toList());
			if (contents.size() > 0){
				for (int i = 0; i < contents.size(); i++) {
					String s = contents.get(i);
					contents.set(i,(i+1)+"、"+s);
				}
				map.put("content",StringUtils.join(contents,"\n"));
			}
		}else {
			//加一个整改要求
			List<String> contents = list.stream().filter(l -> StringUtils.isNotBlank(l.getContent()))
					.map(l -> {
						String content = l.getContent();
						if (StringUtils.isNotBlank(l.getSupplementRemarks())){
							content+=("；"+l.getSupplementRemarks());
						}
						//拼接整改要求
						content += ("\n   整改要求: "+l.getRectifyRequirements());
						return content;
					}).collect(Collectors.toList());
			if (contents.size() > 0){
				for (int i = 0; i < contents.size(); i++) {
					String s = contents.get(i);
					contents.set(i,((i+1)+"、"+s));
				}
				map.put("content",StringUtils.join(contents,"\n"));
			}

			//复查情况
			String checkContent = "";
			for (int i = 0; i < list.size(); i++) {
				HiddenDangerDTO dto = list.get(i);
				List<HiddenDangerInfo> infoList = dto.getInfos().stream()
						.filter(d-> null != d.getCheckTime())
						.sorted(Comparator.comparing(HiddenDangerInfo::getCheckTime).reversed())
						.collect(Collectors.toList());
				if (null != infoList && infoList.size() > 0){
					checkContent += (((i+1)+"、"+infoList.get(0).getCheckRemark()+"\n"));
				}else {
					checkContent += (((i+1)+"、无\n"));
				}
			}
			map.put("checkContent",checkContent);

			//检查人
			Set<String> strings = list.stream().map(l -> l.getRectifer()).collect(Collectors.toSet());
			map.put("checkName",StringUtils.join(strings,","));
		}
		//隐患照片
		List<WordImg> imgList = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			if (i%2 == 0){
				WordImg wordImg = new WordImg();
				imgList.add(wordImg);
			}
		}
		for (int i = 0; i < list.size(); i++) {
			HiddenDangerDTO dto = list.get(i);
			if (i%2==0){
				WordImg wordImg = imgList.get(i/2);
				wordImg.setContentOne((i+1)+"、"+dto.getContent());
				if (StringUtils.isNotBlank(dto.getScenePhoto())){
					ImageEntity image = new ImageEntity();
					image.setHeight(230);
					image.setWidth(250);
					image.setType(ImageEntity.URL);
					image.setUrl(dto.getScenePhoto().split(",")[0]);
					wordImg.setImageEntityOne(image);
				}
			}else {
				WordImg wordImg = imgList.get((i - 1)/2);
				wordImg.setContentTwo((i+1)+"、"+dto.getContent());
				if (StringUtils.isNotBlank(dto.getScenePhoto())){
					ImageEntity image = new ImageEntity();
					image.setHeight(230);
					image.setWidth(250);
					image.setType(ImageEntity.URL);
					image.setUrl(dto.getScenePhoto().split(",")[0]);
					wordImg.setImageEntityTwo(image);
				}
			}
		}
		//整理数据
		List<WordImg> list1 = new ArrayList<>();
		imgList.forEach(i->{
			WordImg wordImg1 = new WordImg();
			wordImg1.setImgOne(i.getContentOne());
			wordImg1.setImgTwo(i.getContentTwo());
			WordImg wordImg2 = new WordImg();
			wordImg2.setImgOne(null==i.getImageEntityOne() && null !=i.getContentOne()?"无照片":i.getImageEntityOne());
			wordImg2.setImgTwo(null==i.getImageEntityTwo() && null !=i.getContentTwo()?"无照片":i.getImageEntityTwo());
			list1.add(wordImg1);
			list1.add(wordImg2);
		});
		map.put("imgList",list1);
		//整改照片
		getRphoto(map,list);

		//用easyPoi导出
		XWPFDocument doc = WordExportUtil.exportWord07(new ClassPathResource("templates/"+(type==1?"tword1.docx":"tword2.docx")).getPath(), map);
		//换行
		this.toWrap(doc);
		return doc;
	}

	/**
	 * word换行处理
	 */
	private void toWrap(XWPFDocument doc){
		//处理换行问题
		for (XWPFTable table : doc.getTables()) {// 表格
			for (XWPFTableRow row : table.getRows()) {// 行
				for (XWPFTableCell cell : row.getTableCells()) {// 单元格 : 直接cell.setText()只会把文字加在原有的后面，删除不了文字
					addBreakInCell(cell);
				}
			}
		}
	}

	/**
	 * 换行处理
	 * @param cell
	 */
	private void addBreakInCell(XWPFTableCell cell) {
		if (cell.getText() != null && cell.getText().contains("\n")) {
			for (XWPFParagraph p : cell.getParagraphs()) {
				for (XWPFRun run : p.getRuns()) {// XWPFRun对象定义具有一组公共属性的文本区域
					if (run.getText(0) != null && run.getText(0).contains("\n")) {
						String[] lines = run.getText(0).split("\n");
						if (lines.length > 0) {
							run.setText(lines[0], 0); // set first line into XWPFRun
							for (int i = 1; i < lines.length; i++) {
								// add break and insert new text
								run.addBreak();// 中断
//			                    run.addCarriageReturn();//回车符，但是不起作用
								run.setText(lines[i]);
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 整理整改照片
	 * @param map
	 * @param list
	 */
	private void getRphoto(Map<String, Object> map, List<HiddenDangerDTO> list) {
		List<HiddenDangerDTO> dangerDTOS = BeanUtil.copyToList(list, HiddenDangerDTO.class);
		List<WordImg> imgList1 = new ArrayList<>();
		for (int i = 0; i < dangerDTOS.size(); i++) {
			if (i%2 == 0){
				WordImg wordImg1 = new WordImg();
				imgList1.add(wordImg1);
			}
		}
		for (int i = 0; i < dangerDTOS.size(); i++) {
			HiddenDangerDTO dto = dangerDTOS.get(i);
			if (i%2==0){
				WordImg wordImg1 = imgList1.get(i/2);
				//整改照片
				if (null != dto.getInfos() && dto.getInfos().size()>0){
					HiddenDangerInfo dangerInfo = dto.getInfos().get(0);
					wordImg1.setContentOne((i+1)+"、"+
							(StringUtils.isNotBlank(dangerInfo.getRectifyRemark())?dangerInfo.getRectifyRemark():"无"));
					//图片
					if (StringUtils.isNotBlank(dangerInfo.getRectifyPhoto())){
						ImageEntity image = new ImageEntity();
						image.setHeight(230);
						image.setWidth(250);
						image.setType(ImageEntity.URL);
						image.setUrl(dangerInfo.getRectifyPhoto().split(",")[0]);
						wordImg1.setImageEntityOne(image);
					}
				}else {
					wordImg1.setContentOne((i+1)+"、无");
				}
			}else {
				//整改照片
				WordImg wordImg1 = imgList1.get((i - 1)/2);
				if (null != dto.getInfos() && dto.getInfos().size()>0){
					HiddenDangerInfo dangerInfo = dto.getInfos().get(0);
					wordImg1.setContentTwo((i+1)+"、"+
							(StringUtils.isNotBlank(dangerInfo.getRectifyRemark())?dangerInfo.getRectifyRemark():"无"));
					//图片
					if (StringUtils.isNotBlank(dangerInfo.getRectifyPhoto())){
						ImageEntity image = new ImageEntity();
						image.setHeight(230);
						image.setWidth(250);
						image.setType(ImageEntity.URL);
						image.setUrl(dangerInfo.getRectifyPhoto().split(",")[0]);
						wordImg1.setImageEntityTwo(image);
					}
				}else {
					wordImg1.setContentTwo((i+1)+"、无");
				}
			}
		}
		//整理数据
		List<WordImg> list2 = new ArrayList<>();
		imgList1.forEach(i->{
			WordImg wordImg1 = new WordImg();
			wordImg1.setImgOne(i.getContentOne());
			wordImg1.setImgTwo(i.getContentTwo());
			WordImg wordImg2 = new WordImg();
			wordImg2.setImgOne(null==i.getImageEntityOne() && null !=i.getContentOne()?"无照片":i.getImageEntityOne());
			wordImg2.setImgTwo(null==i.getImageEntityTwo() && null !=i.getContentTwo()?"无照片":i.getImageEntityTwo());
			list2.add(wordImg1);
			list2.add(wordImg2);
		});
		map.put("imgList1",list2);
	}

	/**
	 * 获取我的待办统计
	 * @return
	 */
	@Override
	public HiddenDangerCountDTO getMyCount() {
//		waitCheckNum: 5    //待复查
//		waitRectifyNum: 68   //待整改
		String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
		int waitCheckNum =  baseMapper.getMyWaitCheckNum(tenantId,linkappUserContextProducer.getCurrent().getId());
		int waitRectifyNum = baseMapper.getMyWaitRectifyNum(tenantId,linkappUserContextProducer.getCurrent().getId());
		HiddenDangerCountDTO hiddenDangerCountDTO = new HiddenDangerCountDTO();
		hiddenDangerCountDTO.setWaitCheckNum(waitCheckNum);
		hiddenDangerCountDTO.setWaitRectifyNum(waitRectifyNum);
		return hiddenDangerCountDTO;
	}

	@SneakyThrows
	private void filterNullData(String tenantId,List<HiddenDangerCountDTO> countDTOList, Date startTime) {
		Map<String, List<HiddenDangerCountDTO>> collect = countDTOList.stream()
				.collect(Collectors.groupingBy(HiddenDangerCountDTO::getCreateTimeStr));
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for (int i=0;i<15;i++){
			//%Y-%m-%d
			String format = simpleDateFormat.format(DateUtil.addDay(startTime,i));
			if(CollectionUtil.isEmpty(collect.get(format))){
				HiddenDangerCountDTO countDTO = new HiddenDangerCountDTO();
				countDTO.setCreateTimeStr(format);
				countDTO.setTotalNum(0);
				countDTO.setInTimeFinishedNum(0);
				countDTO.setQualifiedNum(0);
				//将统计的比例改成至今为止的及时整改率与隐患总数的比例
				HiddenDangerCountDTO statistics = baseMapper
						.getStatistics(linkappUserContextProducer.getCurrent().getTenantId(),simpleDateFormat2.parse(format + " 23:59:59"),null,null,null,null);
				//如果数据为空，则给0
				if(statistics.getTotalNum()==null || statistics.getTotalNum().equals(0)){
					countDTO.setFinishRate("0%");
				}else {
					float num = (float) statistics.getQualifiedNum() / statistics.getTotalNum();
					DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
					countDTO.setFinishRate(df.format(num * 100) + "%");
				}
				countDTOList.add(countDTO);
			}else{
				HiddenDangerCountDTO countDTO = collect.get(format).get(0);
				//将统计的比例改成至今为止的及时整改率与隐患总数的比例
				HiddenDangerCountDTO statistics = baseMapper
						.getStatistics(linkappUserContextProducer.getCurrent().getTenantId(),simpleDateFormat2.parse(format + " 23:59:59"),null,null,null,null);
				//如果数据为空，则给0
				if(statistics.getTotalNum()==null || statistics.getTotalNum().equals(0)){
					countDTO.setFinishRate("0%");
				}else {
					float num = (float) statistics.getQualifiedNum() / statistics.getTotalNum();
					DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
					countDTO.setFinishRate(df.format(num * 100) + "%");
				}
				//如果没有数据
//				float num = (float) statistics.getQualifiedNum() / statistics.getTotalNum();
//				DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
//				countDTO.setFinishRate(df.format(num * 100) + "%");
			}
		}
		Collections.sort(countDTOList, new Comparator<HiddenDangerCountDTO>() {
			@SneakyThrows
			@Override
			public int compare(HiddenDangerCountDTO o1, HiddenDangerCountDTO o2) {
				//将时间转换成日期
				String o1createTimeStr = o1.getCreateTimeStr();
				String o2createTimeStr = o2.getCreateTimeStr();
				Date o1Time = simpleDateFormat.parse(o1createTimeStr);
				Date o2Time = simpleDateFormat.parse(o2createTimeStr);
				return Long.valueOf(o1Time.getTime()).compareTo(Long.valueOf(o2Time.getTime()));
			}
		});
	}

	/**
	 * 导出图片实体
	 */
	private class WordImg{
		private int type;
		private String contentOne;
		private String contentTwo;
		private Object imgOne;
		private Object imgTwo;
		private ImageEntity imageEntityOne;
		private ImageEntity imageEntityTwo;

		public String getContentOne() {
			return contentOne;
		}

		public void setContentOne(String contentOne) {
			this.contentOne = contentOne;
		}

		public String getContentTwo() {
			return contentTwo;
		}

		public void setContentTwo(String contentTwo) {
			this.contentTwo = contentTwo;
		}

		public ImageEntity getImageEntityOne() {
			return imageEntityOne;
		}

		public void setImageEntityOne(ImageEntity imageEntityOne) {
			this.imageEntityOne = imageEntityOne;
		}

		public ImageEntity getImageEntityTwo() {
			return imageEntityTwo;
		}

		public void setImageEntityTwo(ImageEntity imageEntityTwo) {
			this.imageEntityTwo = imageEntityTwo;
		}

		public Object getImgOne() {
			return imgOne;
		}

		public void setImgOne(Object imgOne) {
			this.imgOne = imgOne;
		}

		public Object getImgTwo() {
			return imgTwo;
		}

		public void setImgTwo(Object imgTwo) {
			this.imgTwo = imgTwo;
		}

		public int getType() {
			return type;
		}

		public void setType(int type) {
			this.type = type;
		}
	}
}
